/*
 * 文件名: UnsignedNumberUtil.java
 * 
 * 创建日期: 2016年11月30日
 *
 * Copyright(C) 2016, by <a href="mailto:liws@xingyuanauto.com">liws</a>.
 *
 * 原始作者: liws
 *
 */
package com.moli.iov.protocol.util;

import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

/**
 * 无符号数据类型 工具类
 *
 * @author <a href="mailto:liws@xingyuanauto.com">liws</a>
 *
 * @version $Revision$
 *
 * @since 2016年11月30日
 */
public class UnsignedNumberUtil {

	/**
	 * 判断一个byte类型的数字是否为负数,如果为负数需要使用更宽类型的数据类型来接收,
	 * 比如short,int,long等,一般使用short接收.
	 *
	 * @param value
	 * @return
	 */
	public static boolean needWiden(byte value) {
		return (value & 0x80) == 0x80;
	}

	/**
	 * 判断一个short类型的数字是否为负数,如果为负数需要使用更宽类型的数据类型来接收,
	 * 比如int,long等,一般使用int接收.
	 *
	 * @param value
	 * @return
	 */
	public static boolean needWiden(short value) {
		return (value & 0x8000) == 0x8000;
	}

	/**
	 * 判断一个int类型的数字是否为负数,如果为负数需要使用更宽类型的数据类型来接收,
	 * 使用long接收.
	 *
	 * @param value
	 * @return
	 */
	public static boolean needWiden(int value) {
		return (value & 0x80000000) == 0x80000000;
	}

	/**
	 * 判断一个long类型的数字是否为负数,如果为负数需要BigInteger,
	 * 这是因为java基础类型中字节数最多的就是long了,
	 * 超过long表示范围的需要使用java库提供的
	 * BigInteger 对象类型
	 *
	 * @param value
	 * @return
	 */
	public static boolean needWiden(long value) {
		return (value & 0x8000000000000000L) == 0x8000000000000000L;
	}

	/**
	 * byte类型转换为short类型,如果是value>0则直接返回,
	 * java语言自动支持转换,如果value<0则需要处理符号位:
	 * 
	 * @param value
	 * @return
	 */
	public static short toUnsignedByteValue(byte value) {
		if (!needWiden(value)) {
			return value;
		}
		short wideValue = value;
		// 使用 与 运算把高为字节设置为0,符号位为0,该数字为正数
		return (short) (wideValue & 0xff);
	}

	/**
	 * short类型转换为int类型,如果是value>0则直接返回,
	 * java语言自动支持转换,如果value<0则需要处理符号位:
	 * 
	 * @param value
	 * @return
	 */
	public static int toUnsignedShortValue(short value) {
		if (!needWiden(value)) {
			return value;
		}
		int wideValue = value;
		return wideValue & 0xffff;
	}

	/**
	 * int类型转换为long类型,如果是value>0则直接返回,
	 * java语言自动支持转换,如果value<0则需要处理符号位
	 * 
	 * @param value
	 * @return
	 */
	public static long toUnsignedIntValue(int value) {
		if (!needWiden(value)) {
			return value;
		}
		long wideValue = value;
		return wideValue & 0xffffffffL;
	}

	/**
	 * long类型转换为BigInteger类型,如果是value>0则直接返回,
	 * java语言自动支持转换,如果value<0则需要处理符号位:
	 * 
	 * @param value
	 * @return
	 */
	public static BigInteger toUnsignedLongValue(long value) {
		if (!needWiden(value)) {
			return BigInteger.valueOf(value);
		}
		ByteBuffer buffer = ByteBuffer.allocate(Long.SIZE / Byte.SIZE);
		buffer.order(ByteOrder.BIG_ENDIAN);
		buffer.putLong(value);
		return new BigInteger(1, buffer.array());
	}

	/**
	 * 大端 短整形 转 无符号1字节byte
	 * 
	 * @param i
	 * @return
	 */
	public static byte[] toUnsignedByte(short i) {
		byte[] bytes = new byte[1];
		bytes[0] = (byte) (i & 0xff);
		return bytes;
	}
	
	/**
	 * 大端 整形 转 无符号2字节整形
	 * 
	 * @param i
	 * @return
	 */
	public static byte[] toUnsignedShort(int i) {
		byte[] bytes = new byte[2];
		bytes[0] = (byte) (i >> 8 & 0xff);
		bytes[1] = (byte) (i & 0xff);
		return bytes;
	}
	
	/**
	 * 大端 长整形 转 无符号4字节整形
	 * 
	 * @param l
	 * @return
	 */
	public static byte[] toUnsignedInt(long l) {
		byte[] bytes = new byte[4];
		bytes[0] = (byte) (l >> 24 & 0xff);
		bytes[1] = (byte) (l >> 16 & 0xff);
		bytes[2] = (byte) (l >> 8 & 0xff);
		bytes[3] = (byte) (l >> 0 & 0xff);
		return bytes;
	}
	public static void main(String[] args) {
		
	}
}
